#include "rtos_bsp.h"

static char bsp_printf_buffer[128];
extern void en25qh128a_qspi_xip_init(void);

static void qspi_gpio_config(void)
{
  gpio_init_type gpio_init_struct;

  /* enable the qspi clock */
  crm_periph_clock_enable(CRM_QSPI1_PERIPH_CLOCK, TRUE);

  /* enable the pin clock */
	crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOF_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOG_PERIPH_CLOCK, TRUE);

  /* set default parameter */
  gpio_default_para_init(&gpio_init_struct);

  /* configure the io0 gpio */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = GPIO_PINS_6;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_10);

  /* configure the io1 gpio */
  gpio_init_struct.gpio_pins = GPIO_PINS_7;
  gpio_init(GPIOA, &gpio_init_struct);
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_10);

  /* configure the io2 gpio */
  gpio_init_struct.gpio_pins = GPIO_PINS_4;
  gpio_init(GPIOC, &gpio_init_struct);
  gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE4, GPIO_MUX_10);

  /* configure the io3 gpio */
  gpio_init_struct.gpio_pins = GPIO_PINS_5;
  gpio_init(GPIOC, &gpio_init_struct);
  gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE5, GPIO_MUX_10);

  /* configure the sck gpio */
  gpio_init_struct.gpio_pins = GPIO_PINS_1;
  gpio_init(GPIOB, &gpio_init_struct);
  gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE1, GPIO_MUX_9);

  /* configure the cs gpio */
  gpio_init_struct.gpio_pins = GPIO_PINS_10;
  gpio_init(GPIOB, &gpio_init_struct);
  gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE10, GPIO_MUX_9);
}

void qspi_xip_config(void)
{
  /* qspi config */
  qspi_gpio_config();

  /* switch to cmd port */
  qspi_xip_enable(QSPI1, FALSE);

  /* set sclk */
  qspi_clk_division_set(QSPI1, QSPI_CLK_DIV_4);

  /* set sck idle mode 0 */
  qspi_sck_mode_set(QSPI1, QSPI_SCK_MODE_0);

  /* set wip in bit 0 */
  qspi_busy_config(QSPI1, QSPI_BUSY_OFFSET_0);
	en25qh128a_qspi_xip_init();
}

int uart_printf_rtos(char *format, ...)
{
	va_list aptr;
	int ret;
	
	taskENTER_CRITICAL();
	va_start(aptr, format);
	ret = vsprintf(bsp_printf_buffer, format, aptr);
	va_end(aptr);

	DMA1_CHANNEL6->dtcnt_bit.cnt = ret;
	DMA1_CHANNEL6->maddr = (uint32_t)bsp_printf_buffer;
	dma_channel_enable(DMA1_CHANNEL6, TRUE);
	while(dma_flag_get(DMA1_FDT6_FLAG) == RESET);
	dma_flag_clear(DMA1_FDT6_FLAG);
	dma_channel_enable(DMA1_CHANNEL6, FALSE);
	taskEXIT_CRITICAL();

	return ret;
}

void delay_init_rtos(void)
{
	crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE);
	
	tmr_base_init(TMR6, 0, 287);
	tmr_cnt_dir_set(TMR6, TMR_COUNT_UP);
	tmr_one_cycle_mode_enable(TMR6, TRUE);
	//tmr_flag_clear(TMR6, TMR_OVF_FLAG);
}

void delay_us_rtos(uint32_t nus)
{
	tmr_period_value_set(TMR6, nus - 1);
	tmr_counter_enable(TMR6, TRUE);
	while(tmr_flag_get(TMR6, TMR_OVF_FLAG) != SET);
	tmr_flag_clear(TMR6, TMR_OVF_FLAG);
}

void delay_ms_rtos(uint16_t nms)
{
	while(nms--)
	{
		delay_us_rtos(1000);
	}
}